package com.beijiteshop.shop.ui.home.fragment

import android.graphics.drawable.Drawable
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentTransaction
import androidx.recyclerview.widget.GridLayoutManager
import com.beijiteshop.libcommon.base.adapter.showEmpty
import com.beijiteshop.libcommon.base.adapter.showError
import com.beijiteshop.libcommon.base.adapter.showLoading
import com.beijiteshop.libcommon.base.adapter.showNetError
import com.beijiteshop.libcommon.ext.databinding.bindView
import com.beijiteshop.libcommon.utils.DensityUtil
import com.beijiteshop.shop.R
import com.beijiteshop.shop.app.PageIndex
import com.beijiteshop.shop.base.BaseContainerFragment
import com.beijiteshop.shop.databinding.FragmentHomeBinding
import com.beijiteshop.shop.model.entity.ProductItemEntity
import com.beijiteshop.shop.ui.detail.ProductDetailFragment
import com.beijiteshop.shop.ui.home.adapter.ProductAdapter
import com.beijiteshop.shop.ui.home.adapter.ImageBannerAdapter
import com.beijiteshop.shop.ui.home.vm.HomeVM
import com.beijiteshop.shop.ui.search.fragment.SearchFragment
import com.beijiteshop.shop.utils.HomeGridItemDecoration
import com.blankj.utilcode.util.KeyboardUtils
import com.youth.banner.Banner
import org.koin.android.viewmodel.ext.android.viewModel

/**
 * 首页Fragment
 */
class HomeFragment : BaseContainerFragment(R.layout.fragment_home) {

    private val mBinding: FragmentHomeBinding by bindView()
    private var mProductAdapter: ProductAdapter = ProductAdapter(mutableListOf())
    private var mBanner: Banner<String,ImageBannerAdapter>? = null
    private val mHomeVM: HomeVM by viewModel()

    private var mSearchFragment: SearchFragment? = null
    private var mTransaction: FragmentTransaction? = null

    private var mPage = INIT_PAGE

    companion object {
        private const val INIT_PAGE = 1

        @JvmStatic
        fun newInstance() = HomeFragment()
    }

    override fun initView(view: View) {
        initBanner()
        initRecyclerView()
    }

    override fun initData() {

    }

    override fun initEvent() {
        startObserve()

        mBinding.homeCategoryTv.setOnClickListener {
            startActivity(PageIndex.CATEGORY)
        }

        mBinding.homeSearchEt.setOnEditorActionListener { v, actionId, event ->
            if (actionId == EditorInfo.IME_ACTION_SEARCH){
                doSearch()
                return@setOnEditorActionListener true
            }
            false
        }

        mBinding.homeSearchEt.addTextChangedListener(object : TextWatcher{
            override fun afterTextChanged(s: Editable?) {
                val text = mBinding.homeSearchEt.text
                if (text.isEmpty()){
                    hideSearchFragment()
                    showHideKeyBroad(false)
                }
            }

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

            }
        })

        mBinding.homeSearchIv.setOnClickListener {
            doSearch()
        }
    }

    private fun startObserve(){
        mHomeVM.apply {
            mHomeVM.liveHomeData.observeKt { data ->
                if (mPage == INIT_PAGE){
                    mProductAdapter.setNewInstance(data)
                }else{
                    updateRVState(false,data)
                }
            }

            mHomeVM.liveEmpty.observeKt {
                if (mPage == INIT_PAGE){
                    mProductAdapter.showEmpty { initHomeData() }
                }else{
                    updateRVState(false,null)
                }
            }

            mHomeVM.liveError.observeKt {
                if (mPage == INIT_PAGE){
                    mProductAdapter.showError { initHomeData() }
                }else{
                    updateRVState(true,null)
                }
            }

            mHomeVM.liveNetError.observeKt {
                if (mPage == INIT_PAGE){
                    mProductAdapter.showNetError { initHomeData() }
                }else{
                    updateRVState(true,null)
                }
            }
        }
    }

    override fun onLazyLoad() {
        initHomeData()
    }

    private fun initBanner(){
        mBanner = Banner(this.context)
        mBanner!!.apply {
            val param = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,DensityUtil.dp2px(requireContext(),200))
            layoutParams = param
            addBannerLifecycleObserver(this@HomeFragment)
            val drawables = mutableListOf<Drawable>()
            drawables.add(ContextCompat.getDrawable(requireContext(),R.drawable.tab1)!!)
            adapter = ImageBannerAdapter(drawables)
        }
    }

    /**
     * 初始化首页数据
     */
    private fun initHomeData(){
        mProductAdapter.showLoading()
        mHomeVM.getHomeGoods(INIT_PAGE)
    }

    private fun initRecyclerView(){
        mProductAdapter.apply {
            loadMoreModule.setOnLoadMoreListener {
                mPage++
                requestData(mPage)
            }
            setGridSpanSizeLookup { _, _, position ->
                return@setGridSpanSizeLookup mProductAdapter.data[position].spanSize
            }

            setOnItemClickListener { _, _, position ->
                if ((data[position].itemType == ProductItemEntity.TYPE_COMMON_GOODS
                            || data[position].itemType == ProductItemEntity.TYPE_RUSH_GOODS)
                    && data[position].data!=null){
                    val product = data[position].data
                    //打开商品详情页
                    product?.let {
                        val bundle = Bundle().apply {
                            putParcelable(ProductDetailFragment.BUNDLE_PRODUCT,product)
                        }
                        startActivity(PageIndex.PRODUCT_DETAIL,bundle)
                    }
                }
            }
        }
        mBanner?.let {
            mProductAdapter.addHeaderView(it)
        }
        mBinding.homeProductRv.addItemDecoration(HomeGridItemDecoration(10))
        mBinding.homeProductRv.layoutManager = GridLayoutManager(requireContext(),
            ProductItemEntity.SPAN_SIZE)
        mBinding.homeProductRv.adapter = mProductAdapter
    }

    /**
     * 获取数据
     */
    private fun requestData(page: Int){
        mHomeVM.loadMoreProducts(page)
    }

    /**
     * 更新列表加载状态
     */
    private fun updateRVState(error: Boolean,data: MutableList<ProductItemEntity>?){
        if (error){
            if (mProductAdapter.loadMoreModule.isLoading){
                mProductAdapter.loadMoreModule.loadMoreFail()
            }
        }else{
            if (mProductAdapter.loadMoreModule.isLoading){
                if (data.isNullOrEmpty()){
                    mProductAdapter.loadMoreModule.loadMoreEnd()
                }else{
                    mProductAdapter.addData(data)
                    mProductAdapter.loadMoreModule.loadMoreComplete()
                }
            }
        }
    }

    private fun doSearch(){
        val key = mBinding.homeSearchEt.text.toString()
        if (key.isNotEmpty()){
            showSearchFragment(key)
        }
    }

    /**
     * 显示搜索结果列表
     */
    private fun showSearchFragment(key: String){
        mBinding.homeProductContainerFl.visibility = View.VISIBLE
        mSearchFragment = SearchFragment.newInstance(key)
        mTransaction = childFragmentManager.beginTransaction()
        mTransaction!!.replace(R.id.home_product_container_fl,mSearchFragment!!,"")
        mTransaction!!.addToBackStack(null)
        mTransaction!!.commitAllowingStateLoss()
        showHideKeyBroad(false)
    }

    /**
     * 隐藏搜索结果列表
     */
    private fun hideSearchFragment(){
        mSearchFragment?.also { fragment ->
            mTransaction?.hide(fragment)
            mBinding.homeProductContainerFl.visibility = View.GONE
        }
    }

    private fun showHideKeyBroad(show: Boolean){
        if (show) {
            KeyboardUtils.showSoftInput(this.requireActivity())
        } else {
            KeyboardUtils.hideSoftInput(this.requireActivity())
        }
    }
}